import numpy as np
from time import time
#https://blog.csdn.net/yh1009/article/details/131893419

def 汉明码(lst):   #传入lst，方便管理数据
    def 十进制转二进制列表(十进制数, 输出多少位):
        a = bin(十进制数)
        a = str(a)
        a = a.replace('0b', '')
        # print(a)
        要补的0 = 输出多少位 - len(a)
        lst = []
        for i in range(要补的0):
            lst.append('0')  # 注意，这里的0是str的0，不要传错了
        for i in a:
            lst.append(i)
        return (lst)

    def 汉明码校验位计算(n):  # 2的k次方>=n+k+1
        k = 1
        while 1:
            if 2 ** k >= n + k + 1:
                break
            k += 1
        # print(k)
        return k
    数据位=len(lst)
    校验位=[]
    数据位二进制列表=[]
    校验位长度=汉明码校验位计算(数据位)
    for i in range(校验位长度):
        校验位.append(2**i)
    print('传入数据为',lst,'校验位为',校验位,'(校验位从1开始编码)')
    总位数=数据位+len(校验位)
    # print(总位数)
    #分组,从右往左开始数第一位有1的为一组，第二位有1的位第二组，以此类推。,分组的数量和校验位位数一样，3个校验位就分三组
    # 比如1、3、5、7分为第一组，因为其二进制(001,011,101,111)的右1都是1
    for _ in range(1,总位数+1):
        a=十进制转二进制列表(_,len(校验位))
        数据位二进制列表.append(a)
    print(f'最后的校验码一共有{总位数}位,把这些数转为校验位宽度的二进制列表，为',数据位二进制列表)

    分组表=[]
    def 单个分组(从右数第几位是1,lst):   #lst传进二维列表，这里传的是数据位二进制列表
        newlst=[]
        i=1
        for llst in lst:
            if llst[-从右数第几位是1]=='1':
                newlst.append(i)
            i+=1
        # print(newlst)
        return newlst
    for i in range(1,len(校验位)+1):
        a=单个分组(i,数据位二进制列表)
        分组表.append(a)
    print('分组,从右往左开始数第一位有1的为一组，第二位有1的位第二组，以此类推。,分组的数量和校验位位数一样，3个校验位就分三组')
    print('比如1、3、5、7分为第一组，因为其二进制(001,011,101,111)的右1都是1')
    print('分组结果为',分组表)

    #将校验位的数据用未知数替代（因为汉明码就是在检验位的位置放新数）
    含未知数的汉明码=[]
    i=0

    for t in range(1,总位数+1):
        if t in 校验位:
            含未知数的汉明码.append('x')
        else:
            含未知数的汉明码.append(lst[i])
            i+=1
    print('含未知数的汉明码为',含未知数的汉明码,'相当于用未知数把校验位先顶掉')

    def 偶检验(分组lst,含未知数汉明码lst,第几个数):
        t=0
        newlst=[]
        奇偶检验=''
        返回值=0
        for i in 分组lst:
            # print(含未知数汉明码lst[i-1])
            newlst.append(含未知数汉明码lst[i-1])
            if 含未知数汉明码lst[i-1]==1:
                t+=1
        if t%2==0:
            奇偶检验='偶'
            返回值 = 0
        else:
            奇偶检验='奇'
            返回值 = 1
        print(f'对{分组lst}进行偶检验,也就是{newlst},含有1的个数为{t},是{奇偶检验}，第{第几个数}个数是{返回值}')
        return 返回值
    补全的汉明码lst=[]
    for i in range(len(校验位)):
        a=偶检验(分组表[i],含未知数的汉明码,i+1)
        补全的汉明码lst.append(a)
    print('故要补全的汉明码为',补全的汉明码lst)

    t=0
    for 索引 in 校验位:
        含未知数的汉明码[索引-1]=补全的汉明码lst[t]
        t+=1
    print('最后输出的汉明码为',含未知数的汉明码)
lst=[1,0,1,1]
汉明码(lst)
